package cn.edu.cug.cs.gtl;

import cn.edu.cug.cs.gtl.common.Pair;
import cn.edu.cug.cs.gtl.protos.TableKey;
import cn.edu.cug.cs.gtl.protos.Tuples;
import cn.edu.cug.cs.gtl.sql.druid.DruidWrapper;
import cn.edu.cug.cs.gtl.sql.executor.SQLExecutor;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.util.*;

/**
 * @author sunjianhao
 */
public class MainFrame extends JFrame{
    public JMenuBar menuBar;

    JTree tree;
    DefaultMutableTreeNode originalDataNode;
    public JPanel nowPanel;
    String url="jdbc:mysql://127.0.0.1:3306/yuman?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
    String username="root";
    String password="sjh020401";
    String roleId;
    String userId;

    /**
     * 使可以通过菜单名称找到对应菜单项的双列集合
     */
    Map<String,JMenuItem> map;


    /**
     * 构造方法
     * @param roleId 用户角色id
     * @param userId 用户id
     */
    public MainFrame(String roleId,String userId){
        //初始化
        setBounds(300,100,800,600);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        //获取当前用户Id
        this.userId=userId;
        //获取当前用户角色Id
        this.roleId=roleId;

        //创建菜单栏
        menuBar=new JMenuBar();
        //将菜单栏加入界面
        setJMenuBar(menuBar);

        //初始化map
        map=new HashMap<>();

        //将对应菜单插入菜单栏
        addMenu("0",new JMenu());

        //创建JTree
        createJTree();

        //tree控件监听
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent evt) {
//                valueChangedPerfed();
            }
        });
        setVisible(true);
        //创建监听函数
        addListener();
    }

    /**
     * 创建监听函数
     */
    private void addListener() {
        //原始数据
        JMenuItem rawDataMenu=map.get("原始数据");
        rawDataMenu.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setContentPane(new RawDataFrame().getContentPane());
                setVisible(true);
            }
        });

        //关系数据
        JMenuItem relationalDataMenu=map.get("关系数据");
        relationalDataMenu.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

            }
        });
    }


    /**
     * 构建窗口右侧表格
     * @return panel
     */
    private JPanel createNowPanel() {
        return new JPanel();
    }

    /**
     * 创建树
     */
    private void createJTree() {
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
        //创建二级节点
        originalDataNode = new DefaultMutableTreeNode("原始数据");

        // 把二级节点作为子节点添加到根节点
        rootNode.add(originalDataNode);

        //创建其它子节点
        addChildrenNode(originalDataNode);

        // 使用根节点创建树组件
        tree = new JTree();
        TreeModel treeModel = new DefaultTreeModel(rootNode);
        tree.setModel(treeModel);
        tree.setRootVisible(false);

        JScrollPane scrollPane = new JScrollPane(tree);
        scrollPane.setPreferredSize(new Dimension(150,this.getHeight()));
        this.getContentPane().add(scrollPane,BorderLayout.WEST);
    }


    private void addChildrenNode(DefaultMutableTreeNode rootNode) {
        //获取当前目录下的所有子目录
        ArrayList<String> childrenNodeNameList=getAllChildrenNodeName(rootNode);
        for (int i = 0; i < childrenNodeNameList.size(); i++) {
            DefaultMutableTreeNode newNode=new DefaultMutableTreeNode(childrenNodeNameList.get(i));
            rootNode.add(newNode);
            //递归添加节点
            addChildrenNode(newNode);
        }
    }

    private ArrayList<String> getAllChildrenNodeName(DefaultMutableTreeNode rootNode) {
        return new ArrayList<String>();
    }

    /**
     * 插入菜单项
     */
    private boolean addMenu(String parentId,JMenu parentMenu) {
        //设置返回值——用于判断级别为菜单或目录但用户菜单或数据库中无其子菜单的情况
        boolean answer=false;
        try{
            //设置TableKey
            TableKey tableKey = TableKey.newBuilder()
                    .setUrl(url)
                    .setUserName(username)
                    .setPassword(password)
                    .setSchemaName("DBS")
                    .build();

            //查出符合的菜单并插入菜单栏
            //当前角色为管理员
            String adminRoleId="1";
            Tuples p;
            if(adminRoleId.equals(roleId)) {
                p = getAdminSubmenus(tableKey, Integer.parseInt(parentId));
            } else {
                p=getUserSubmenus(tableKey,Integer.parseInt(parentId),Integer.parseInt(userId));
            }
            //其菜单下无子菜单情况——直接返回退出函数
            if(p.getTupleCount()==0) {
                return answer;
            }
            //将查出的菜单逐一插入
            for (int i=0;i<p.getTupleCount();i++) {
                //为目录级菜单
                if("0".equals(parentId)) {
                    JMenu menu=new JMenu(p.getTuple(i).getValue(1));
                    menuBar.add(menu);
                    //将此目录下的菜单或按钮查询并插入此目录
                    addMenu(p.getTuple(i).getValue(0),menu);
                } else if(!"0".equals(parentId)) { //为菜单级
                    JMenu menu=new JMenu(p.getTuple(i).getValue(1));
                    parentMenu.add(menu);
                    answer=true;
                    //将本菜单下的菜单或者按钮调用本函数插入本菜单
                    //标识为菜单，但是数据库中暂不存在此菜单的子按钮或子菜单，则将菜单改为按钮
                    if(!addMenu(p.getTuple(i).getValue(0),menu)) {
                        parentMenu.remove(menu);
                        JMenuItem subMenuItem=new JMenuItem(p.getTuple(i).getValue(1));
                        parentMenu.add(subMenuItem);
                        map.put(p.getTuple(i).getValue(1),subMenuItem);
                    }
                } else {//为按钮级
                    JMenuItem menuItem=new JMenuItem(p.getTuple(i).getValue(1));
                    parentMenu.add(menuItem);
                    map.put(p.getTuple(i).getValue(1),menuItem);
                    answer=true;
                }
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return answer;
    }

    /**
     * 获取子菜单——用户
     * @param menuTableKey
     * @param menuID
     * @param userID
     * @return
     * @throws Exception
     */
    public static Tuples getUserSubmenus(TableKey menuTableKey, int menuID, int userID) throws Exception{
        String sql = "SELECT\n" +
                "\tt.menu_id,\n" +
                "\tt.menu_name \n" +
                "FROM\n" +
                "\t(\n" +
                "\tSELECT\n" +
                "\t\tmenu_id,\n" +
                "\t\tparent_id,\n" +
                "\t\torder_num,\n" +
                "\t\tmenu_name \n" +
                "\tFROM\n" +
                "\t\tsys_menu \n" +
                "\tWHERE\n" +
                "\t\tmenu_id IN (\n" +
                "\t\tSELECT\n" +
                "\t\t\tmenu_id \n" +
                "\t\tFROM\n" +
                "\t\t\tsys_role_menu \n" +
                "\t\tWHERE\n" +
                "\t\trole_id IN ( SELECT role_id FROM sys_user_role WHERE user_id = ? ))) t \n" +
                "WHERE\n" +
                "\tt.parent_id = ? \n" +
                "ORDER BY\n" +
                "\tt.order_num";

        Connection connection = DruidWrapper.getConnection(menuTableKey);
        cn.edu.cug.cs.gtl.common.Pair<String,Object[]> p = new Pair<>();
        p.setKey(sql);
        Object[] objects = new Object[2];
        objects[0] = Long.valueOf(userID);
        objects[1] = Long.valueOf(menuID);
        p.setValue(objects);
        Tuples tuples = SQLExecutor.executeQuery(connection,p);
        connection.close();
        return tuples;
    }

    /**
     * 获取子菜单——管理员
     * @param menuTableKey
     * @param menuID
     * @return
     * @throws Exception
     */
    public static Tuples getAdminSubmenus(TableKey menuTableKey, int menuID) throws Exception{
        String sql = "SELECT\n" +
                "\tt.menu_id,\n" +
                "\tt.menu_name \n" +
                "FROM\n" +
                "\t(\n" +
                "\tSELECT\n" +
                "\t\tmenu_id,\n" +
                "\t\tparent_id,\n" +
                "\t\torder_num,\n" +
                "\t\tmenu_name \n" +
                "\tFROM\n" +
                "\t\tsys_menu ) t \n" +
                "WHERE\n" +
                "\tt.parent_id = ? \n" +
                "ORDER BY\n" +
                "\tt.order_num";

        Connection connection = DruidWrapper.getConnection(menuTableKey);
        cn.edu.cug.cs.gtl.common.Pair<String,Object[]> p = new Pair<>();
        p.setKey(sql);
        Object[] objects = new Object[1];
        objects[0] = Long.valueOf(menuID);
        p.setValue(objects);
        Tuples tuples = SQLExecutor.executeQuery(connection,p);
        connection.close();
        return tuples;
    }
}
